package com.huilian.iotbox.admin.service.impl;

import com.huilian.iotbox.admin.dao.AgencyDao;
import com.huilian.iotbox.admin.service.AgencyService;
import com.huilian.iotbox.admin.service.UserRoleService;
import com.huilian.iotbox.admin.service.UserService;
import com.huilian.iotbox.data.common.ServerResponse;
import com.huilian.iotbox.data.dto.AgencyDto;
import com.huilian.iotbox.data.dto.UserDto;
import com.huilian.iotbox.data.enums.*;
import com.huilian.iotbox.data.po.Agency;
import com.huilian.iotbox.data.po.SystemConfig;
import com.huilian.iotbox.data.po.User;
import com.huilian.iotbox.data.po.UserRole;
import com.huilian.iotbox.data.service.SystemConfigService;
import com.huilian.iotbox.data.vo.AgencyVo;
import com.huilian.iotbox.data.vo.UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Author mineChen
 * @Date: 2020/4/6 11:11
 */
@Slf4j
@Service
@Transactional
public class AgencyServiceImpl implements AgencyService {

    @Resource
    private AgencyDao agencyDao;
    @Resource
    private UserService userService;
    @Resource
    private PasswordEncoder passwordEncoder;
    @Resource
    private UserRoleService userRoleService;
    @Autowired
    private SystemConfigService systemConfigService;

    @Override
    public List<Agency> findAgencyIdAndName(Integer agencyId) {
        return agencyDao.findAgencyIdAndName(agencyId);
    }

    @Override
    public ServerResponse findListByKeyword(UserInfo userInfo, AgencyDto agencyDto) {
        // 当根据条件查询的时候不查询当前登录的机构，而是查询条件下的机构
//            User currentAgentUser = userService.findUserById(userInfo.getId());
//            /**
//             * 先找到当前登录用户
//             * 第一步全部查出当前用户的所有下级代理
//             * 第二步根据集合获取当前用户的顶级代理
//             * 第三步搞定所有子代理
//             */
//            Agency agency = agencyDao.findOneAgencyById(currentAgentUser.getAgencyId());
        agencyDto.setUserInfo(userInfo);
        List<AgencyVo> agencyList = new ArrayList<>();

        if (userInfo.getRoleId().equals(RoleEnum.FINANCE.getRoleId())) {
            List<AgencyVo> agencyVoList = agencyDao.findByKeywordByFinanceAgency(agencyDto);
            for (AgencyVo a : agencyVoList) {
                AgencyVo agencyVo = this.getParentAgency(agencyVoList, a);
                if (!ObjectUtils.isEmpty(agencyVo)) {
                    if (!agencyList.contains(agencyVo)) {
                        agencyList.add(agencyVo);
                    }
                }
            }
        } else {
            agencyList = agencyDao.findOneAgencyByKeywordOrAgencyId(agencyDto);
        }

        if (!StringUtils.isEmpty(agencyList)) {
            List<AgencyVo> agencyVos = new ArrayList<>();
            for (AgencyVo agencyVo : agencyList) {
                agencyDto.setLevel(agencyVo.getLevel() + 1);
                List<AgencyVo> agencyVoList = agencyDao.findAllByKeyword(agencyDto);

                // 找到所有顶级机构和商户
                List<AgencyVo> topAgencyList = agencyVoList.stream().filter(item ->
                        item.getParentId().equals(agencyVo.getId())
                ).map((item2) -> {
                    item2.setChildren(getChildren(item2, agencyVoList));
                    return item2;
                }).collect(Collectors.toList());

                agencyVo.setChildren(topAgencyList);
//        AgencyVo agencyVo = CopyPropertiesUtils.CopyProperties(agency, AgencyVo.class);
//        agencyVo.setUsername(currentAgentUser.getUsername());
//        agencyVo.setChildren(topAgencyList);
//        agencyVo.setName(currentAgentUser.getName());
//        agencyVo.setMobile(currentAgentUser.getMobile());
//        agencyVo.setProvince(currentAgentUser.getProvince() == null ? "" : currentAgentUser.getProvince());
//        agencyVo.setCity(currentAgentUser.getCity() == null ? "" : currentAgentUser.getCity());

                agencyVos.add(agencyVo);
            }
            return ServerResponse.createBySuccess(agencyVos);
        } else {
            return ServerResponse.createBySuccess("");
        }
    }

    private AgencyVo getParentAgency(List<AgencyVo> list, AgencyVo agencyVo) {
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).getId().equals(agencyVo.getParentId())) {
                return this.getParentAgency(list, list.get(i));
            }
            if (i == list.size() - 1) {
                return agencyVo;
            }
        }
        return null;
    }

    @Override
    public ServerResponse checkBussAuthNum(String bussAuthNum, Integer agencyId, UserInfo userInfo) {
        Integer count = agencyDao.checkBussAuthNum(bussAuthNum, userInfo, agencyId);
        if (count > 0) {
            return ServerResponse.createByErrorMessage("已存在!");
        } else {
            return ServerResponse.createBySuccess();
        }
    }

    @Override
    public int checkAbbreviation(String alias, Integer id) {
        return agencyDao.checkAbbreviation(alias, id);

    }

    /**
     * 生成机构号
     *
     * @param agency
     * @return
     */
    @Override
    public String createAgencyNo(Agency agency) {
        //机构号第一位
        int firstNum = 1;
        //下级机构号第二位和机构等级相同
        Integer secondNum = agency.getLevel() + 1;
        int length = secondNum.toString().length();
        List<Integer> list = agencyDao.findagencyNoByLevel(agency.getLevel() + 1);
        int thirdNum = 001;
        if (list.size() > 0) {
            String max = Collections.max(list).toString();
            //截取出机构号第三位数+1
            thirdNum = Integer.parseInt(max.substring(length + 1));
            thirdNum = thirdNum + 1;
        }
        String thirdNumStr = String.format("%03d", thirdNum);
        String agencyNo = String.valueOf(firstNum) + String.valueOf(secondNum) + thirdNumStr;

        //跳过4、7
        if (agencyNo.contains("4")) {
            agencyNo = agencyNo.replace('4', '5');
        } else if (agencyNo.contains("7")) {
            agencyNo = agencyNo.replace('7', '8');
        }
        return agencyNo;
    }

    @Override
    public List<Agency> getAllAgencyOfName(UserInfo userInfo) {
        return agencyDao.getAllAgencyOfName(userInfo);
    }

    @Override
    public AgencyDto getUserAgencyByUserId(Integer userId) {
        return agencyDao.getUserAgencyByUserId(userId);
    }

    @Override
    public List<Agency> findListByStatus(Integer status) {
        return agencyDao.findListByStatus(status);
    }

    @Override
    public Agency findOneAgencyById(Integer agencyId) {
        return agencyDao.findOneAgencyById(agencyId);
    }

    @Override
    public Integer findSetAgencyNoTrade(Set<Integer> set) {
        return agencyDao.findSetAgencyNoTrade(set);
    }

    @Override
    public ServerResponse findAgency(Integer agencyId, UserInfo userInfo) {
        AgencyVo agencyVo = agencyDao.findAgency(agencyId, userInfo);

        if (agencyVo != null) {
            return ServerResponse.createBySuccess(agencyVo);
        } else {
            return ServerResponse.createByErrorMessage("获取数据失败");
        }
    }

    @Override
    public List<AgencyVo> findAgencyByLoginUser(AgencyDto agencyDto) {
        List<AgencyVo> agencyVoList = agencyDao.findAgencyByLoginUser(agencyDto);
        return sort(agencyVoList, 0);
    }

    @Override
    public ServerResponse changeAgencyStatus(AgencyDto agencyDto) {
        if (!agencyDto.getUserInfo().getRoleId().equals(RoleEnum.SUPER_ADMINISTRATOR.getRoleId())) {
            if (agencyDto.getStatus() == 1) {
                return ServerResponse.createByErrorMessage("你没有权限冻结机构！");
            } else {
                return ServerResponse.createByErrorMessage("你没有权限恢复机构！");
            }
        }
        Agency agency = agencyDao.findOneAgencyById(agencyDto.getId());
        List<Agency> agencyList = new ArrayList<>();
        agencyList.add(agency);
        this.findAgencyAndChildrenAgency(agency.getId(), agencyList);

        agencyList.forEach(data -> {
            data.setStatus(agencyDto.getStatus());
            agencyDao.update(data);
            UserDto userDto = new UserDto();
            userDto.setId(data.getUserId());
            userDto.setLockStatus(agencyDto.getStatus() == 1 ? true : false);
            userService.updateUser(userDto);
        });

        return ServerResponse.createBySuccess();
    }

    /**
     * 修改机构自定义logo
     *
     * @param agencyDto
     * @param userInfo
     * @return
     */
    @Override
    public ServerResponse updateCustomLogo(AgencyDto agencyDto, UserInfo userInfo) {
        if (!RoleEnum.SUPER_ADMINISTRATOR.getRoleId().equals(userInfo.getRoleId())) {
            return ServerResponse.createByErrorMessage("您没有权限操作该方法");
        }
        // type:1、开关，2、PC端logo，3、移动端logo

        if (StringUtils.isEmpty(agencyDto.getId())) {
            return ServerResponse.createByErrorMessage("缺少机构id");
        }

        if (StringUtils.isEmpty(agencyDto.getType())) {
            return ServerResponse.createByErrorMessage("缺少类型");
        }

        if (agencyDto.getType() == 1) {
            if (StringUtils.isEmpty(agencyDto.getCustomLogo())) {
                return ServerResponse.createByErrorMessage("缺少开关属性");
            }
        } else if (agencyDto.getType() == 2) {
            if (StringUtils.isEmpty(agencyDto.getPcLogoFileName())) {
                return ServerResponse.createByErrorMessage("缺少PC端logo");
            }
        } else if (agencyDto.getType() == 3) {
            if (StringUtils.isEmpty(agencyDto.getMobileLogoFileName())) {
                return ServerResponse.createByErrorMessage("缺少移动端logo");
            }
        } else {
            return ServerResponse.createByErrorMessage("类型有误");
        }

        Agency agency = agencyDao.findOneAgencyById(agencyDto.getId());
        if (StringUtils.isEmpty(agency)) {
            return ServerResponse.createByErrorMessage("合作伙伴不存在");
        }

        Agency agency1 = new Agency();
        agency1.setId(agencyDto.getId());
        agency1.setCustomLogo(agencyDto.getCustomLogo());
        agency1.setPcLogoFileName(agencyDto.getPcLogoFileName());
        agency1.setMobileLogoFileName(agencyDto.getMobileLogoFileName());
        agencyDao.update(agency1);

        return ServerResponse.createBySuccess();
    }

    @Override
    public Agency findOneAgencyByUserId(Integer userId) {
        if (StringUtils.isEmpty(userId)) {
            return null;
        }
        return agencyDao.findOneAgencyByUserId(userId);
    }

    @Override
    public String findDefaultBurningDeviceIdById(Integer id) {
        AgencyVo agencyVo = agencyDao.findDefaultBurningDeviceIdById(id);
        if (!StringUtils.isEmpty(agencyVo) && !StringUtils.isEmpty(agencyVo.getDeviceNo())){
            return agencyVo.getDeviceNo();
        }
        return null;
    }

    private void findAgencyAndChildrenAgency(Integer parentId, List<Agency> agencyList) {
        List<Agency> agencies = agencyDao.findByParentId(parentId);
        if (!ObjectUtils.isEmpty(agencies)) {
            agencyList.addAll(agencies);
            agencies.forEach(data -> {
                this.findAgencyAndChildrenAgency(data.getId(), agencyList);
            });
        }
    }

    private static List<AgencyVo> sort(List<AgencyVo> list, int id) {
        List<AgencyVo> result = new ArrayList<AgencyVo>();
        for (AgencyVo a : list) {
            a.setTitle(a.getAlias());
            a.setKey(a.getId());
            if (a.getParentId() == id) {
                result.add(a);
                a.setChildren(sort(list, a.getId()));
            }
        }
        return result;
    }

    /**
     * 递归查找所有子机构、子商户
     *
     * @param agencyVo
     * @param agencyVoList
     * @return
     */
    private List<AgencyVo> getChildren(AgencyVo agencyVo, List<AgencyVo> agencyVoList) {

        List<AgencyVo> children = agencyVoList.stream().filter(item -> {
            return item.getParentId().equals(agencyVo.getId());
        }).map(item2 -> {
            // 找到子机构、子商户
            item2.setChildren(getChildren(item2, agencyVoList));
            return item2;
        }).collect(Collectors.toList());

        return children;
    }

    @Override
    public ServerResponse add(AgencyDto agencyDto, UserInfo userInfo) {
        if (userInfo.getRoleId().equals(RoleEnum.FINANCE.getRoleId())) {
            return ServerResponse.createByErrorMessage("你没有权限添加机构！");
        }
        // 获取当前登录的Id的user信息
        User currentAgentUser = userService.findUserById(userInfo.getId());
        log.info("--------currentAgentUser--------" + currentAgentUser.toString());

        // 调用校验参数方法，如果返回null说明没有非法参数，否则直接抛出错误
        ServerResponse serverResponse = this.checkParam(agencyDto);
        if (!StringUtils.isEmpty(serverResponse)) {
            return serverResponse;
        }


        if (!StringUtils.isEmpty(agencyDto.getId()) && agencyDto.getId() > 0) {
            ServerResponse.createByErrorMessage("暂不支持修改");
            // 判断当前登录的账号是否在修改自己的user信息
//            if (agencyDto.getUser().getId().equals(userInfo.getId())) {
//                return ServerResponse.createByErrorMessage("您没有权限修改");
//            }
//            // 编辑机构
//            User user = new User();
//            user.setId(agencyDto.getUser().getId());
//            user.setName(agencyDto.getUser().getName());
//            user.setIdCardNo(agencyDto.getUser().getIdCardNo());
//            user.setProvince(agencyDto.getUser().getProvince());
//            user.setCity(agencyDto.getUser().getCity());
//            user.setDistrict(agencyDto.getUser().getDistrict());
//            user.setAddress(agencyDto.getUser().getAddress());
//            user.setCertPhotoA(agencyDto.getUser().getCertPhotoA());
//            user.setCertPhotoB(agencyDto.getUser().getCertPhotoB());
//            userService.update(user);
//            Agency agency = new Agency();
//            agency.setAlias(agencyDto.getAlias());
//            agency.setName(agencyDto.getName());
//            agency.setType(agencyDto.getType());
//            agency.setBussAuthNum(agencyDto.getBussAuthNum());
//            agency.setLicensePhoto(agencyDto.getLicensePhoto());
//            agency.setWxFee(agencyDto.getFee());
//            agency.setAliFee(agencyDto.getFee());
//            agency.setTiktokRate(agencyDto.getTiktokRate());
//            agency.setMeiTuanRate(agencyDto.getMeiTuanRate());
//            agency.setId(agencyDto.getId());
//            agencyDao.update(agency);
        } else {
            // 校验费率非空
            if (StringUtils.isEmpty(agencyDto.getFee())) {
                return ServerResponse.createByErrorMessage("费率不能为空！");
            }

            // 校验登录密码非空
            if (StringUtils.isEmpty(agencyDto.getUser().getPassword())) {
                return ServerResponse.createByErrorMessage("登录密码不能为空！");
            }

            //费率除100
            BigDecimal fee = agencyDto.getFee().divide(new BigDecimal("100"));
            agencyDto.setFee(fee);
            BigDecimal tiktokRate = agencyDto.getTiktokRate().divide(new BigDecimal("100"));
            agencyDto.setTiktokRate(tiktokRate);
            BigDecimal meiTuanRate = agencyDto.getMeiTuanRate().divide(new BigDecimal("100"));
            agencyDto.setMeiTuanRate(meiTuanRate);

            // 找到当前机构的费率，然后要比下级费率低
            // 如果是添加就查询当前机构的费率，如果是修改就查询上级机构费率
            Agency topAgency = new Agency();
            if (!StringUtils.isEmpty(agencyDto.getId()) && agencyDto.getId() > 0) {
                Agency agency = agencyDao.findOneAgencyById(agencyDto.getId());
                topAgency = agencyDao.findOneAgencyByParentId(agency.getParentId());

            } else {
                topAgency = agencyDao.findOneAgencyByUserId(userInfo.getId());
            }
            log.info("--------topAgency--------" + topAgency.toString());
            log.info(topAgency.getWxFee() + "--------顶级机构-下级机构--------" + agencyDto.getFee());

            if (new BigDecimal(0).compareTo(agencyDto.getFee()) >= 0) {
                return ServerResponse.createByErrorMessage("请正确输入代理费率！");
            }

            if (agencyDto.getFee().compareTo(topAgency.getWxFee()) == -1) {
                return ServerResponse.createByErrorMessage("下级机构费率必须大于当前机构费率！");
            }

            if (agencyDto.getFee().compareTo(new BigDecimal("0.00600")) > 0) {
                return ServerResponse.createByErrorMessage("机构费率必须小于0.6%！");
            }

            /**
             * 添加负责人 begin
             */
            SystemConfig systemConfig = systemConfigService.findOneSystemConfigById(1);
            User newUserInfo = agencyDto.getUser();
            newUserInfo.setBalance(new BigDecimal(0));//初始化金额默认为0
            newUserInfo.setStatus(UserStatusEnum.ENABLED.getCode());
            newUserInfo.setPassword(passwordEncoder.encode(agencyDto.getUser().getPassword()));
            newUserInfo.setOperatePassword(passwordEncoder.encode(agencyDto.getUser().getMobile()));
            newUserInfo.setVersion(0);
            newUserInfo.setCertPhotoA(agencyDto.getUser().getCertPhotoA());
            newUserInfo.setCertPhotoB(agencyDto.getUser().getCertPhotoB());
            newUserInfo.setIdCardNo(agencyDto.getUser().getIdCardNo());
            newUserInfo.setSalesmanId(userInfo.getId());
            newUserInfo.setProvince(agencyDto.getUser().getProvince());
            newUserInfo.setCity(agencyDto.getUser().getCity());
            newUserInfo.setDistrict(agencyDto.getUser().getDistrict());
            newUserInfo.setReceiptType(MchTypeEnum.OWN.getCode());
            newUserInfo.setDockingStatus(DockingStatusEnum.CLOSE.getCode());
            newUserInfo.setCardStatus(CardStatusEnum.CLOSE.getCode());
            newUserInfo.setPayeeUserId(0);
            newUserInfo.setWelfareReturnCoinSum(systemConfig.getDistributeWelfareToMemberByMaxCoin());
            log.info("--------newUserInfo--------" + newUserInfo.toString());
            int userAddCount = userService.insert(newUserInfo);
            /**
             * 添加负责人 end
             */

            /**
             * 添加机构 begin
             */
            // 查询当前用户机构信息
            Agency agency = agencyDao.findOneAgencyById(currentAgentUser.getAgencyId());
            log.info("--------agency--------" + agency.toString());
            // 生成机构号
            agencyDto.setUserId(newUserInfo.getId());
            agencyDto.setLevel(agency.getLevel() + 1);
            agencyDto.setSalesmanId(userInfo.getId());
            agencyDto.setAgencyNo(createAgencyNo(agency));
            agencyDto.setStatus(OpenStatusEnum.OPEN.getCode());
            agencyDto.setAgencyType(1);
            agencyDto.setParentId(agency.getId());
            agencyDto.setWxFee(agencyDto.getFee());
            agencyDto.setAliFee(agencyDto.getFee());
            agencyDto.setFeeType(FeeTypeEnum.D1.getCode());
            agencyDto.setWithdrawRate(new BigDecimal(0.08));
            agency.setTiktokRate(agencyDto.getTiktokRate());
            agency.setMeiTuanRate(agencyDto.getMeiTuanRate());
            log.info("--------agencyDto--------" + agencyDto.toString());
            agencyDao.insert(agencyDto);
            log.info("--------agencyDto--------" + agencyDto.toString());
            /**
             * 添加机构 end
             */

            /**
             * 添加角色 end
             */
            UserRole userRole = new UserRole();
            userRole.setUserId(newUserInfo.getId());
            userRole.setRoleId(RoleEnum.AGENT.getRoleId());
            userRoleService.insert(userRole);
            /**
             * 添加角色 end
             */

            newUserInfo.setAgencyId(agencyDto.getId());
            userService.update(newUserInfo);
            log.info("--------newUserInfo--------" + newUserInfo.toString());
        }

        return ServerResponse.createBySuccess();
    }

    private ServerResponse checkParam(AgencyDto agencyDto) {

        if (StringUtils.isEmpty(agencyDto)) {
            return ServerResponse.createByErrorMessage("机构各项信息不能为空！");
        }

        // 个人资质类型时，校验身份证非空
        if (agencyDto.getType().equals(AgencyAptitudeTypeEnum.PERSON.getCode()) && StringUtils.isEmpty(agencyDto.getUser().getIdCardNo())) {
            return ServerResponse.createByErrorMessage("身份证号码不能为空！");
        }

        // 个体户、有限公司资质类型时，校验营业执照号码非空
        if (!agencyDto.getType().equals(AgencyAptitudeTypeEnum.PERSON.getCode()) && StringUtils.isEmpty(agencyDto.getBussAuthNum())) {
            return ServerResponse.createByErrorMessage("营业执照号码不能为空！");
        }

        // 校验代理全称非空
        if (StringUtils.isEmpty(agencyDto.getName())) {
            return ServerResponse.createByErrorMessage("全称不能为空！");
        }

        // 校验代理简称非空
        if (StringUtils.isEmpty(agencyDto.getAlias())) {
            return ServerResponse.createByErrorMessage("简称不能为空！");
        }
        if (StringUtils.isEmpty(agencyDto.getId())) {
            // 校验登录账号非空
            if (StringUtils.isEmpty(agencyDto.getUser().getUsername())) {
                return ServerResponse.createByErrorMessage("登录账号不能为空！");
            }

            // 校验手机号非空
            if (StringUtils.isEmpty(agencyDto.getUser().getMobile())) {
                return ServerResponse.createByErrorMessage("手机号不能为空！");
            }
        }

        // 校验负责人姓名非空
        if (StringUtils.isEmpty(agencyDto.getUser().getName())) {
            return ServerResponse.createByErrorMessage("负责人姓名不能为空！");
        }

        // 个人、个体户、有限公司资质类型时，校验是否有上传身份证正面
//        if (StringUtils.isEmpty(agencyDto.getUser().getCertPhotoA())) {
//            return ServerResponse.createByErrorMessage("请上传身份证正面！");
//        }

        // 个人、个体户、有限公司资质类型时，校验是否有上传身份证正面
//        if (StringUtils.isEmpty(agencyDto.getUser().getCertPhotoB())) {
//            return ServerResponse.createByErrorMessage("请上传身份证反面！");
//        }

        // 个体户、有限公司资质类型时，校验是否有上传营业执照
//        if (!agencyDto.getType().equals(AgencyAptitudeTypeEnum.PERSON.getCode()) && StringUtils.isEmpty(agencyDto.getLicensePhoto())) {
//            return ServerResponse.createByErrorMessage("请上传营业执照！");
//        }

        // 查看该简称是否存在
        int abbreviationCount = this.checkAbbreviation(agencyDto.getAlias(), agencyDto.getId());
        if (abbreviationCount > 0) {
            return ServerResponse.createByErrorMessage("该机构简称已存在！");
        }

        // 修改机构信息时不需要校验这些
        if (StringUtils.isEmpty(agencyDto.getId())) {
            // 检查登录账号是否已存在
            User userExist = userService.findUserByLoginUserName(agencyDto.getUser().getUsername(), UserStatusEnum.WRITE_OFF.getCode());
            if (!StringUtils.isEmpty(userExist)) {
                return ServerResponse.createByErrorMessage("该登录账号已被注册！");
            }

            // 校验手机号是否唯一
            ServerResponse serverResponse = userService.checkMobile(agencyDto.getUser().getMobile());
            if (!serverResponse.getIsSuccess()) {
                return ServerResponse.createByErrorMessage("该手机号已被注册！");
            }
        }

        return null;
    }


}
